/****************************************************************************
 *  _____       ______  _____
 * |_   _|     |  ____|/ ____|
 *   | |  _ __ | |__  | (___    Institute of Embedded Systems
 *   | | | '_ \|  __|  \___ \   Zürcher Hochschule für Angewandte
 *  _| |_| | | | |____ ____) |  Wissenschaften
 * |_____|_| |_|______|_____/   8401 Winterthur, Switzerland
 *
 ****************************************************************************
 *
 * @version $Rev: 204 $
 * @author  $Author: bacr $
 * @date    $Date: 2013-12-20 16:54:25 +0100 (ven., 20 déc. 2013) $
 *
 ***************************************************************************/

#ifndef __PACKET_H__
#define __PACKET_H__

#include "object.h"

#include "packet/net_address.h"

typedef struct packet_t         packet_t;
typedef struct info_packet_t    info_packet_t;
typedef struct info_header_t    info_header_t;
typedef uint32_t                packet_type_t;

#define PACKET_TYPE_ETHERNET                0x00000001
#define PACKET_TYPE_VLAN                    0x00000002
#define PACKET_TYPE_ARP                     0x00000004
#define PACKET_TYPE_IPV4                    0x00000010
#define PACKET_TYPE_IPV6                    0x00000020
#define PACKET_TYPE_UDP                     0x00000040
#define PACKET_TYPE_TCP                     0x00000080
#define PACKET_TYPE_PTP2                    0x00000100
#define PACKET_TYPE_PTP2_SIGNALING          0x00000200
#define PACKET_TYPE_PTP2_ANNOUNCE           0x00000400
#define PACKET_TYPE_IGNORE                  0x80000000

#define INFO_HEADER                   \
    packet_type_t               type; \

struct info_header_t {
    INFO_HEADER
};

struct info_packet_t {
    object_t                    obj;
    INFO_HEADER
};

#include "packet/raw_packet.h"
#include "packet/ethernet_packet.h"
#include "packet/ip_packet.h"
#include "packet/udp_packet.h"
#include "packet/ptp2_packet.h"
#include "packet/ptp2_signaling_packet.h"
#include "packet/ptp2_announce_packet.h"

struct packet_t {
    union {
        info_packet_t           info;
        ethernet_packet_t       ether;
        ip_packet_t             ip;
        udp_packet_t            udp;
        ptp2_packet_t           ptp2;
        ptp2_signaling_packet_t ptp2_sig;
        ptp2_announce_packet_t  ptp2_announce;
    };
};

bool     packet_init(packet_t *this);
uint32_t packet_encode(packet_t *this, raw_packet_t *raw_packet);
void     packet_decode(packet_t *this, raw_packet_t *raw_packet);

#endif

